/* Copyright (C) 2003 Univ. of Massachusetts Amherst, Computer Science Dept.
   This file is part of "MALLET" (MAchine Learning for LanguagE Toolkit).
   http://www.cs.umass.edu/~mccallum/mallet
   This software is provided under the terms of the Common Public License,
   version 1.0, as published by http://www.opensource.org.  For further
   information, see the file `LICENSE' included with this distribution. */
package jp.ac.tohoku.ecei.cl.www.base;

import gnu.trove.iterator.*;
//import gnu.trove.list.array.*;
import gnu.trove.map.hash.*;
//import gnu.trove.set.hash.*;

import java.io.Serializable;
import java.io.ObjectOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;

/**
 * Hash map that maps integer pairs to objects.
 * This uses much less space than an 2d array, if the mapping is sparse.
 *
 * Created: Dec 14, 2005
 *
 * @author <A HREF="mailto:casutton@cs.umass.edu>casutton@cs.umass.edu</A>
 * @version $Id: MIntInt2ObjectMap.java,v 1.3 2006/02/22 04:28:34 casutton Exp $
 */
public class MIntInt2IntMap implements Serializable {

    private TIntObjectHashMap<TIntIntHashMap> backing = new TIntObjectHashMap<TIntIntHashMap> ();

    public MIntInt2IntMap () { }

    public void put (int key1, int key2, int value)
    {
        if (!backing.containsKey (key1)) {
            TIntIntHashMap inner = new TIntIntHashMap();
            backing.put (key1, inner);
        }
        TIntIntHashMap inner = (TIntIntHashMap) backing.get (key1);
        inner.put(key2, value);
    }

    public void increment (int key1, int key2) {
        if (!backing.containsKey (key1)) {
            TIntIntHashMap inner = new TIntIntHashMap();
            backing.put (key1, inner);
        }
        TIntIntHashMap inner = (TIntIntHashMap) backing.get (key1);
        if (!inner.containsKey(key2)) {
            inner.put(key2, 0);
        }
        inner.put(key2, inner.get(key2) + 1);
    }
    
    public int get (int key1, int key2)
    {
        TIntIntHashMap inner = (TIntIntHashMap) backing.get (key1);
        if (inner == null) {
            return Integer.MIN_VALUE;
        } else {
            return inner.get (key2);
        }
    }

    public boolean containsKey (int key1, int key2)
    {
        TIntIntHashMap inner = (TIntIntHashMap) backing.get (key1);
        if (inner == null) {
            return false;
        } else {
            return inner.containsKey (key2);
        }
    }

    /** Returns an array of first-level keys. */
    public int[] keys1 () {
        return backing.keys ();
    }

    public int[] keys2 (int key1)
    {
        TIntIntHashMap inner = (TIntIntHashMap) backing.get (key1);
        return inner.keys ();
    }

    public static void main (String[] args) {
        MIntInt2IntMap map = new MIntInt2IntMap();
        map.put(1,1,2);
        map.put(1,2,3);
        System.err.println(map.get(1,1));
        System.err.println(map.get(1,2));
    }
}
